﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Twodi.Aspect.Interfaces;
using Twodi.Interfaces;
using Twodi.Aspect.Implemented;
using Twodi.Behavior.Interfaces;
using Twodi.Behavior.Implemented;
using Twodi.Input;
using Twodi.Input.Events;
using Twodi.Arguments;

namespace Twodi.Implemented
{
    public abstract class AbstractBasic : DrawableGameComponent, IPositionAspect, ISizeAspect, IRotationAspect, IBoundsAspect, IScaleAspect, IKeyboardBehavior, IMouseBehavior
    {
        public AbstractBasic(Game game)
            : base(game)
        {
            this.PositionProperties = new PositionAspect();
            this.SizeProperties = new SizeAspect();
            this.RotationProperties = new RotationAspect();
            this.BoundsProperties = new BoundsAspect(this);
            this.ScaleProperties = new ScaleAspect(this);
            this.KeyboardInput = new KeyboardBehavior(this);
            this.MouseInput = new MouseBehavior(this);
        }

        public virtual bool Handle(KeyboardInput input)
        {
            onPreHandle(new InputEventArgs<KeyboardInput>(input));
            bool returning = KeyboardInput.Handle(input);
            onPosHandle(new InputEventArgs<KeyboardInput>(input));
            return returning;
        }

        public virtual bool Handle(MouseInput input)
        {
            onPreHandle(new InputEventArgs<MouseInput>(input));
            bool returning = MouseInput.Handle(input);
            onPosHandle(new InputEventArgs<MouseInput>(input));
            return returning;
        }

        public Vector2 Position
        {
            get
            {
                return this.PositionProperties.Position;
            }
            set
            {
                this.PositionProperties.Position = value;
            }
        }

        public Vector2 Size
        {
            get
            {
                return this.SizeProperties.Size;
            }
            set
            {
                this.SizeProperties.Size = value;
            }
        }

        public Vector2 Center
        {
            get
            {
                return this.SizeProperties.Center;
            }
        }

        public Vector2 Origin
        {
            get
            {
                return this.RotationProperties.Origin;
            }
            set
            {
                this.RotationProperties.Origin = value;
            }
        }

        public float Rotation
        {
            get
            {
                return this.RotationProperties.Rotation;
            }
            set
            {
                this.RotationProperties.Rotation = value;
            }
        }

        public Rectangle Bounds
        {
            get
            {
                return this.BoundsProperties.Bounds;
            }
        }

        public float Scale
        {
            get
            {
                return this.ScaleProperties.Scale;
            }
            set
            {
                this.ScaleProperties.Scale = value;
            }
        }

        public IPosition PositionProperties
        {
            get;
            set;
        }

        public ISize SizeProperties
        {
            get;
            set;
        }

        public IRotation RotationProperties
        {
            get;
            set;
        }

        public IBounds BoundsProperties
        {
            get;
            set;
        }

        public IScale ScaleProperties
        {
            get;
            set;
        }

        public KeyboardBehavior KeyboardInput
        {
            get;
            set;
        }

        public MouseBehavior MouseInput
        {
            get;
            set;
        }

        /// <summary>
        /// Evento invocado antes de ser iniciado o Handle(Mouse);
        /// </summary>
        public event EventHandler<InputEventArgs<MouseInput>> PreMouseHandle;

        /// <summary>
        /// Evento invocado após ser finalizado o Handle(Mouse);
        /// </summary>
        public event EventHandler<InputEventArgs<MouseInput>> PosMouseHandle;

        /// <summary>
        /// Evento invocado antes de ser iniciado o Handle(Keyboard);
        /// </summary>
        public event EventHandler<InputEventArgs<KeyboardInput>> PreKeyboardHandle;

        /// <summary>
        /// Evento invocado após ser finalizado o Handle(Keyboard);
        /// </summary>
        public event EventHandler<InputEventArgs<KeyboardInput>> PosKeyboardHandle;

        /// <summary>
        /// Método invocado antes de ser iniciado o Handle();
        /// </summary>
        protected virtual void onPreHandle(InputEventArgs<MouseInput> e)
        {
            if (PreMouseHandle != null)
            {
                PreMouseHandle(this, e);
            }
        }

        /// <summary>
        /// Método invocado após de ser finalizado o Handle();
        /// </summary>
        protected virtual void onPosHandle(InputEventArgs<MouseInput> e)
        {
            if (PosMouseHandle != null)
            {
                PosMouseHandle(this, e);
            }
        }/// <summary>
        /// Método invocado antes de ser iniciado o Handle();
        /// </summary>
        protected virtual void onPreHandle(InputEventArgs<KeyboardInput> e)
        {
            if (PreKeyboardHandle != null)
            {
                PreKeyboardHandle(this, e);
            }
        }

        /// <summary>
        /// Método invocado após de ser finalizado o Handle();
        /// </summary>
        protected virtual void onPosHandle(InputEventArgs<KeyboardInput> e)
        {
            if (PosKeyboardHandle != null)
            {
                PosKeyboardHandle(this, e);
            }
        }
    }
}
